#pragma once
#include "../../Struct.h"
#include "../../GLTFParser.h"
namespace sq {

class Util {
public:
	// lines
	static void toKuantiData(CVector<::LineArg>& outData, const CVector<sq::LineArg>& inData) {
		for (const auto& arg : inData) {
			::LineArg line;
			line.tag = arg.tag;
			line.eq = arg.eq;
			line.style = arg.style;
			line.color = arg.color;
			outData << line;
		}
	}

	// models
	static void toKuantiData(CVector<::ModelArg>& outData, const CVector<sq::ModelArg>& inData) {
		for (const auto& arg : inData) {
			::ModelArg model;
			model.ID = arg.id;
			model.type = arg.type;
			const float ZOffset = GLTFParser::info(model.type).maxZ;
			model.pos = P(arg.pos.x, arg.pos.z - ZOffset);// SQ: z is aligned to the rear of the model
			model.angle = arg.angle;// already turned to radians
			outData << model;
		}
	}

	/******************************** Raw Line ************************************************/
	static LineStyle lineStyle(int type) {
		switch(type) {
			case 1: return LineStyle::Solid;
			case 2: return LineStyle::RoadEdge;
			case 3: return LineStyle::Dashed;
			case 4: return LineStyle::Dashed_Solid;
			case 5: return LineStyle::Solid_Dashed;
			case 6: return LineStyle::Double_Dashed;
			case 7: return LineStyle::Double_Solid;
			case 8: return LineStyle::Deceleration_Solid;
			case 9: return LineStyle::Deceleration_Dashed;
		}
		return LineStyle::Solid;
	}

	static CColor lineColor(int colour) {
		switch(colour) {
			case 0: return "white";
			case 1: return "yellow";
		}
		return Config::Line_DefColor;
	}

	/******************************** Raw Model ************************************************/
	static ModelType modelType(int objClass) {
		switch (objClass) {
			case 0: return ModelType::Car;
			case 1: return ModelType::Truck;
			case 2: return ModelType::Moto;
			case 3: return ModelType::Person;
			case 4: return ModelType::Cone;
			case 5: return ModelType::Barrier;
			case 6: return ModelType::Unknown;
		}
		return ModelType::Unknown;
	}

	static int modelTypeValue(ModelType type) {
		switch (type) {
			case ModelType::Car: return 0;
			case ModelType::Truck: return 1;
			case ModelType::Moto: return 2;
			case ModelType::Person: return 3;
			case ModelType::Cone: return 4;
			case ModelType::Barrier: return 5;
			case ModelType::Unknown: return 6;
		}
		return -1;
	}

	static P modelPos(float hDist, float vDist) {// left-positive(-X), front-positive(-Z)
		return P(-hDist, -vDist);
	}

	/******************************** Standalone Status ************************************/
	/******************************** Standalone Status ************************************/
	static sq::ACC acc(int value) {
		if (value == 2)
			return sq::ACC::Follow;
		else if (value == -100)
			return sq::ACC::Off;
		return sq::ACC::INVALID;
	}

	static sq::FCW fcw(int value) {
		if (value == 5)
			return sq::FCW::Yellow;
		else if (value == 6 || value == 7)
			return sq::FCW::Red;
		else if (value == -100)
			return sq::FCW::Off;
		return sq::FCW::INVALID;
	}

	static sq::ALC alc(int value) {
		if (value == 4)
			return sq::ALC::Left;
		else if (value == 5)
			return sq::ALC::Right;
		else if (value == -100)
			return sq::ALC::Off;
		return sq::ALC::INVALID;
	}

	static sq::NOA noa(int value) {
		if (value == 2)
			return sq::NOA::On;
		else if (value == -100)
			return sq::NOA::Off;
		return sq::NOA::INVALID;
	}

	static sq::ACAS acas(int value) {
		if (value == 2)
			return sq::ACAS::Left;
		else if (value == 3)
			return sq::ACAS::Right;
		else if (value == -100)
			return sq::ACAS::Off;
		return sq::ACAS::INVALID;
	}
};

};// end namespace